package com.zx.springsecurity.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.zx.springsecurity.entity.Users;

@RestController
@RequestMapping("/test")
public class TestController {

	@GetMapping("hello")
	public String hello(){
		return "test";
	}
	
	@GetMapping("index")
	public ModelAndView  index(){
        return new ModelAndView("index");
	}
	
	/**
	 * 测试Spring Security权限控制（使用注解方式）
	 * 
	 * 权限注解：
	 * 一、@Secured（不好用） 启动类上开启该注解 用@EnableGlobalMethodSecurity(securedEnabled = true)
	 * 二、@jsr250（用它还要导入其他包） 启动类上开启该注解 用@EnableGlobalMethodSecurity(jsr250Enabled = true)
	 * 三、@PreAuthorize（最好用） 启动类上开启该注解 用@EnableGlobalMethodSecurity(prePostEnabled = true)
	 * 1).@PreAuthorize : 在调用方法之前验证权限，支持Spring EL表达式，也叫SPEL表达式，还可以自定义表达式
	 * 2).@PostAuthorize : 使用不多，在方法执行后再进行权限验证，适合验证带有返回值的权限
	 * 3).@PostFilter : 权限验证之后对数据进行过滤，对返回值过滤
	 * 4).@PreFilter : 进入控制器之前对数据进行过滤，对参数过滤
	 *    
	 * SPEL表达式：
	 * 1).hasRole : 用于匹配一个使用
	 * 2).hasAnyRole : 匹配其中的任何一个均可放行。
	 * 3).permitAll : 任何用户均可访问，即直接放行
	 * 4).denyAll : 任何用户均不可访问 
	 * 5).anonymous :　匿名用户可访问
	 * 6).authenticated :　认证过可访问
	 * 7).rememberMe : 通过remember me 功能认证的 可访问
	 * 8).fullyAuthenticated : 通过提供完整的凭证信息来认证的 
	 * 9).principal : 允许直接访问主体对象，表示当前用户
	 * 10).authentication : 允许直接访问当前 Authentication对象 从SecurityContext中获得
	 * 11).isAnonymous() : 如果用户是一个匿名登录的用户 就会返回 true
	 * 12).isRememberMe() : 如果用户是通过remember-me 登录的用户 就会返回 true
	 * 13).isAuthenticated() 如果用户不是匿名用户就会返回true
	 * 14).isFullyAuthenticated() 如果用户不是通过匿名也不是通过remember-me登录的用户时， 就会返回true。
	 * 15).hasAuthority() 有某个权限即可访问
	 * @return
	 */
	@GetMapping("update")
	//@Secured(value={"ROLE_A", "ROLE_B"})
	//拥有角色ROLE_USER并且当前登录的账号为zhangsan
	//@PreAuthorize("hasRole('ROLE_USER') and 'zhangsan' == authentication.principal.username")
	//拥有权限menu:system才能访问
	//@PreAuthorize("hasAnyAuthority('menu:system')")
	//@PostAuthorize("hasAnyAuthority('menu:system')")
	//权限验证之后对数据进行过滤，对返回值过滤，留下用户名是admin1的数据
	@PostFilter("filterObject.username == 'admin1'")
	//进入控制器之前对数据进行过滤，对参数过滤，
	//@PreFilter("filterObject.id%2==0")
	//public List<Users> update(List<Users> list2){
	public List<Users> update(){
		System.out.println("进入update");
		List<Users> list = new ArrayList<>();
		Users user1 = new Users();
		user1.setId(1);
		user1.setPassword("6666");
		user1.setUsername("admin1");
		Users user2 = new Users();
		user2.setId(2);
		user2.setPassword("8888");
		user2.setUsername("admin2");
		list.add(user1);
		list.add(user2);
		return list;
	}
}
